package cn.yangliu.nacos.management.service.sys.impl;

import java.util.List;
import java.util.Optional;

import static cn.yangliu.nacos.management.constant.CacheConstants.AUTHORITY_CACHE;

import cn.yangliu.jpa.base.service.impl.JpaServiceImpl;
import cn.yangliu.nacos.comm.enums.GlobalResultCode;
import cn.yangliu.nacos.comm.ex.GlobalException;
import cn.yangliu.nacos.management.entity.sys.Authority;
import cn.yangliu.nacos.management.model.AuthorityInsertModel;
import cn.yangliu.nacos.management.model.AuthorityUpdateModel;
import cn.yangliu.nacos.management.repository.sys.AuthorityRepository;
import cn.yangliu.nacos.management.repository.sys.Role2AuthorityRepository;
import cn.yangliu.nacos.management.service.sys.AuthorityService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * The type of nacos.
 *
 * @author 问道于盲
 * @date 2020 -01-01
 */
@Service
@Transactional(rollbackFor = Throwable.class)
public class AuthorityServiceImpl extends JpaServiceImpl<Authority, Long, AuthorityRepository>
        implements AuthorityService {

    /**
     * current class instance's member.
     * The Role 2 authority repository.
     */
    @Autowired
    private Role2AuthorityRepository role2AuthorityRepository;

    /**
     * Insert authority.
     *
     * @param model the model
     * @return the authority
     */
    @Override
    public Authority insert(AuthorityInsertModel model) {
        Authority authority = new Authority();
        BeanUtils.copyProperties(model, authority);
        return repository.save(authority);
    }

    /**
     * Update authority.
     *
     * @param model the model
     * @return the authority
     */
    @Override
    @CacheEvict(cacheNames = AUTHORITY_CACHE, allEntries = true)
    public Authority update(AuthorityUpdateModel model) {
        Optional<Authority> optional = repository.findById(model.getId());
        if (!optional.isPresent()) {
            throw new GlobalException(GlobalResultCode.DATA_NOT_EXIST);
        }
        Authority authority = optional.get();
        BeanUtils.copyProperties(model, authority);
        return repository.save(authority);
    }

    /**
     * Find authorities by oauth 2 id list.
     *
     * @param oauth2Id the oauth 2 id
     * @return the list
     */
    @Override
    @Cacheable(cacheNames = AUTHORITY_CACHE, key = "#root.methodName + #oauth2Id")
    public List<Authority> findAuthoritiesByOauth2Id(Long oauth2Id) {
        return repository.findAuthoritiesByOauth2Id(oauth2Id);
    }

    /**
     * Find all authorities list.
     *
     * @return the list
     */
    @Override
    @Cacheable(cacheNames = AUTHORITY_CACHE, key = "#root.methodName")
    public List<Authority> findAllAuthorities() {
        return repository.findAllAuthorities();
    }

    /**
     * Delete by id.
     *
     * @param id the id
     */
    @Override
    @CacheEvict(cacheNames = AUTHORITY_CACHE, allEntries = true)
    public void deleteById(Long id) {
        role2AuthorityRepository.deleteByAuthorityId(id);
        super.deleteById(id);
    }
}
